#include <bits/stdc++.h>
#define int long long
using namespace std;

const double eps = 1e-10;

int T, n, m, L, V, ans1, ans2, p[100005], s[1000005], byd[100005], f[1000005], maxl[1000005];

struct node
{
	int d, v, a, l, r;
} car[100005]; 

deque < int > q;

int dis(int v0, int A, double t)
{
	return floor(1.0 * v0 * t + 0.5 * 1.0 * A * t * t);
}

int dis2(int v0, int A, double t)
{
	return ceil(1.0 * v0 * t + 0.5 * 1.0 * A * t * t);
}

signed main()
{
	freopen("detect.in", "r", stdin);
	freopen("detect.out", "w", stdout);
	scanf("%lld", &T);
	while (T--)
	{
		scanf("%lld%lld%lld%lld", &n, &m, &L, &V);
		L++;
		for (int i = 1; i <= n; i++)
			byd[i] = 0;
		for (int i = 1; i <= L; i++)
			s[i] = 0;
		ans1 = 0;
		while (!q.empty()) q.pop_back();
		for (int i = 1; i <= n; i++)
		{
			scanf("%lld%lld%lld", &car[i].d, &car[i].v, &car[i].a);		
			car[i].d++;
		}
		for (int i = 1; i <= m; i++)
		{
			scanf("%lld", &p[i]);
			p[i]++;
			s[p[i]] = 1;
		}
		for (int i = 1; i <= L; i++)
			s[i] += s[i - 1];
		for (int i = 1; i <= n; i++)
		{
			if (car[i].a < 0)
			{
				if (car[i].v <= V)
				{
					car[i].l = 1919810;
					car[i].r = -1919810;
				}
				else
				{
					car[i].l = car[i].d;
					double t = (car[i].v - V) * 1.0 / (-car[i].a) - eps;
					car[i].r = min(L, car[i].l + dis(car[i].v, car[i].a, t));
				}
			}
			else if (car[i].a > 0)
			{
				if (car[i].v > V)
				{
					car[i].l = car[i].d;
					car[i].r = L;
				}
				else
				{
					double t = (V - car[i].v) * 1.0 / car[i].a + eps;
					if (car[i].d + dis(car[i].v, car[i].a, t) <= L)
					{
						car[i].l = car[i].d + dis2(car[i].v, car[i].a, t);
						car[i].r = L;
					}
					else
					{
						car[i].l = 1919810;
						car[i].r = -1919810;
					}
				}
			}
			else
			{
				if (car[i].v > V) 
				{
					car[i].l = car[i].d;
					car[i].r = L;
				}
				else
				{
					car[i].l = 1919810;
					car[i].r = -1919810;
				}
			}
		}
		for (int i = 1; i <= n; i++)
		{
			if (car[i].l > car[i].r) continue;
			if (s[car[i].r] - s[car[i].l - 1] > 0) 
			{
				ans1++;
				byd[i] = 1;
			}
		}
		for (int i = 1; i <= L; i++)
			maxl[i] = -1;
		for (int i = 1; i <= n; i++)
			if (byd[i]) maxl[car[i].r] = max(maxl[car[i].r], car[i].l);
		f[0] = 0;
		q.push_back(0);
		for (int i = 1; i <= L + 1; i++)
		{
			if (s[i] - s[i - 1] == 0 && i != L + 1) 
			{
				maxl[i] = max(maxl[i - 1], maxl[i]);
				continue;
			}
			while (!q.empty() && q.front() < maxl[i - 1]) q.pop_front();
			f[i] = f[q.front()] + 1;
			while (!q.empty() && f[q.back()] > f[i]) q.pop_back();
			q.push_back(i);
			maxl[i] = max(maxl[i - 1], maxl[i]);
		}
		printf("%lld %lld\n", ans1, m - f[L + 1] + 1); 
	}
	return 0;
}
